# RVC Controller SW — Design Class Diagram

| 항목 | 내용 |
|------|------|
| 문서 번호 | RVC-CD-002 |
| 버전 | v2.0 |
| 작성일 | 2026-05-29 |
| 작성자 | OOAD Team 9 |
| 상태 | 초안 (Draft) |

---

## 변경 이력 (Change History)

| 버전 | 날짜 | 변경 내용 | 작성자 |
|------|------|-----------|--------|
| v1.0 | 2026-05-19 | 최초 작성 — Domain Model + SSD System Operations 기반 Design Class Diagram 도출 | OOAD Team 9 |
| v2.0 | 2026-05-29 | HW 변경 반영 — 우측 장애물 센서 제거. SensorPosition·Controller·ObstacleSensor 변경 | OOAD Team 9 |

---

## v1 → v2 변경 요약 (Change Summary)

| 변경 구분 | 대상 | 변경 내용 |
|-----------|------|-----------|
| **[삭제]** | `SensorPosition.RIGHT` | 우측 HW 센서 제거에 따라 열거값 삭제 |
| **[변경]** | `Controller.-checkSideObstacles()` | 반환 타입 `SensorPosition` → `void`. 좌측 센서만 직접 확인; 우측은 `avoidFrontObstacle()` 내부에서 `turn(RIGHT)` + `front:ObstacleSensor` 재활용으로 간접 확인 |
| **[변경]** | `Controller.-avoidAllDirectionObstacle()` | 메서드 서명 유지, 동작 변경. `turn(BACK)` 제거 → 후진 후 `checkSideObstacles()`와 동일한 방향 재판단 로직 적용 |
| **[변경]** | `ObstacleSensor` 인스턴스 수 | 3개(FRONT·LEFT·RIGHT) → 2개(FRONT·LEFT). 클래스 자체는 유지 |

---

## 1. Design Class Diagram

> Domain Model과의 차이: 메서드(가시성·파라미터·반환타입) 추가, System Operations → Controller 공개 인터페이스 반영

![Design Class Diagram v2](diagrams/class_diagram.png)

---

## 2. 클래스 정의

### RVC
| 구분 | 이름 | 타입 | 설명 | 변경 |
|------|------|------|------|------|
| 속성 | -state | RVCState | 현재 RVC 동작 상태 | — |
| 메서드 | +startCleaning() | void | 청소 시작 — Controller에 위임 | — |

### Controller
| 구분 | 이름 | 파라미터 / 반환 | 설명 | 변경 |
|------|------|----------------|------|------|
| 속성 | -pollingInterval | int | 센서 폴링 주기 (ms, ≤ 100) | — |
| 공개 | +startCleaning() | void | 청소 시작 명령 | — |
| 공개 | +reportObstacle(position) | void | 장애물 센서 → Controller 알림 | — |
| 공개 | +reportDust(dustLevel) | void | 먼지 센서 → Controller 알림 | — |
| 공개 | +reportSensorError(sensorId) | void | 센서 오류 → Controller 알림 | — |
| 비공개 | -avoidFrontObstacle() | void | 전방 장애물 회피. 좌측 확인 → 막히면 turn(RIGHT) + front 센서로 우측 확인 | — |
| 비공개 | -avoidAllDirectionObstacle() | void | 전방향 장애물 회피. turn(BACK) 제거 → 후진 후 방향 재판단 | **[변경]** |
| 비공개 | -boostCleaningPower() | void | 청소 파워 증가 흐름 | — |
| 비공개 | -pollSensors() | void | 주기적 센서 상태 조회 | — |
| 비공개 | -checkSideObstacles() | ~~SensorPosition~~ → **void** | 좌측 센서만 직접 확인. 결과는 내부 상태 필드에 저장 | **[변경]** |
| 비공개 | -recordObstacleDetection(position) | void | 장애물 감지 결과 기록 | — |
| 비공개 | -recordDustDetection(dustLevel) | void | 먼지 감지 결과 기록 | — |
| 비공개 | -validateSensorData(sensorId) | boolean | 센서값 유효성 검사 | — |
| 비공개 | -retainLastValidState() | void | 이전 유효 상태 유지 | — |

> **[변경] `checkSideObstacles()` 반환 타입:**  
> v1: `SensorPosition` 반환 — 좌·우 중 비어 있는 방향을 직접 반환하였음.  
> v2: `void` — 좌측 센서만 확인하고 결과를 내부 필드(`leftObstacle_`)에 저장.  
> 우측 방향 확인은 `avoidFrontObstacle()` 내부에서 `turn(RIGHT)` 기동 후 `front:ObstacleSensor.isObstacleDetected()` 호출로 수행.
>
> **[변경] `avoidAllDirectionObstacle()` 동작:**  
> v1: `stop() → moveBackward() → turn(BACK) → moveForward()`  
> v2: `stop() → moveBackward()` 후 `checkSideObstacles()`와 동일한 방향 판단 로직 재적용.  
> `turn(Direction::BACK)` 호출이 제거되고, 좌측·우측(우회전+전방센서) 재확인 후 회전.

### MovementUnit
| 구분 | 이름 | 파라미터 / 반환 | 설명 | 변경 |
|------|------|----------------|------|------|
| 속성 | -currentDirection | Direction | 현재 이동 방향 | — |
| 속성 | -speed | float | 현재 이동 속도 | — |
| 메서드 | +moveForward() | void | 전방 이동 | — |
| 메서드 | +moveBackward() | void | 후방 이동 | — |
| 메서드 | +stop() | void | 이동 정지 | — |
| 메서드 | +turn(direction) | void | 지정 방향으로 회전 | — |
| 메서드 | +getDirection() | Direction | 현재 방향 반환 | — |

### CleaningUnit
| 구분 | 이름 | 파라미터 / 반환 | 설명 | 변경 |
|------|------|----------------|------|------|
| 속성 | -powerLevel | PowerLevel | 현재 청소 파워 수준 | — |
| 속성 | -boostDuration | int | 파워 부스트 지속 시간 (ms) | — |
| 속성 | -isActive | boolean | 청소 활성화 여부 | — |
| 메서드 | +startCleaning() | void | 청소 시작 | — |
| 메서드 | +setPowerLevel(level) | void | 파워 수준 직접 설정 | — |
| 메서드 | +boostPower() | void | 파워 BOOSTED 전환 | — |
| 메서드 | +restoreNormalPower() | void | 파워 NORMAL 복귀 | — |
| 메서드 | +getIsActive() | boolean | 청소 활성 여부 반환 | — |

### Sensor (abstract)
| 구분 | 이름 | 파라미터 / 반환 | 설명 | 변경 |
|------|------|----------------|------|------|
| 속성 | -sensorId | String | 센서 고유 ID | — |
| 속성 | -status | SensorStatus | 센서 상태 (ACTIVE / ERROR) | — |
| 메서드 | +getStatus() | SensorStatus | 센서 상태 반환 | — |
| 메서드 | +getSensorId() | String | 센서 ID 반환 | — |
| 추상 | +readData()* | Object | 센서 데이터 읽기 (하위 클래스 구현) | — |

### ObstacleSensor
| 구분 | 이름 | 파라미터 / 반환 | 설명 | 변경 |
|------|------|----------------|------|------|
| 속성 | -position | SensorPosition | 센서 위치 (FRONT / LEFT) | **[변경]** |
| 속성 | -obstacleDetected | boolean | 장애물 감지 여부 | — |
| 메서드 | +isObstacleDetected() | boolean | 장애물 유무 반환 | — |
| 메서드 | +getPosition() | SensorPosition | 센서 위치 반환 | — |
| 메서드 | +readData() | boolean | 장애물 감지값 반환 (Sensor 구현) | — |

> **[변경] `ObstacleSensor` 인스턴스:**  
> v1: FRONT · LEFT · RIGHT 총 3개 인스턴스 존재.  
> v2: FRONT · LEFT 총 **2개** 인스턴스만 존재. 클래스 구조 자체는 변경 없음.  
> `front:ObstacleSensor`는 전방 감지 외에 **우측 방향 확인 시 재활용**됨 (turn(RIGHT) 후 `isObstacleDetected()` 호출).

### DustSensor
| 구분 | 이름 | 파라미터 / 반환 | 설명 | 변경 |
|------|------|----------------|------|------|
| 속성 | -dustLevel | float | 측정된 먼지 농도 | — |
| 속성 | -dustDetected | boolean | 먼지 감지 여부 | — |
| 메서드 | +isDustDetected() | boolean | 먼지 유무 반환 | — |
| 메서드 | +getDustLevel() | float | 먼지 농도값 반환 | — |
| 메서드 | +readData() | float | 먼지 농도 반환 (Sensor 구현) | — |

---

## 3. 관계 정의

| 관계 | From | To | 다중성 | 표기 | 의미 | 변경 |
|------|------|----|--------|------|------|------|
| Composition | RVC | Controller | 1:1 | `*--` | RVC 소멸 시 Controller도 소멸 | — |
| Composition | RVC | MovementUnit | 1:1 | `*--` | RVC 소멸 시 MovementUnit도 소멸 | — |
| Composition | RVC | CleaningUnit | 1:1 | `*--` | RVC 소멸 시 CleaningUnit도 소멸 | — |
| Aggregation | Controller | Sensor | 1:1..* | `o--` | 센서는 교체·추가 가능. 실제 인스턴스 수: 3개(2 obstacle + 1 dust) | **[변경]** |
| Association | Controller | MovementUnit | 1:1 | `-->` | 이동 명령 전달 | — |
| Association | Controller | CleaningUnit | 1:1 | `-->` | 청소 명령 전달 | — |
| Generalization | Sensor | ObstacleSensor | — | `<\|--` | 장애물 센서는 Sensor의 구체 구현 | — |
| Generalization | Sensor | DustSensor | — | `<\|--` | 먼지 센서는 Sensor의 구체 구현 | — |
| Dependency | 각 클래스 | Enum | — | `..>` | 타입으로 사용 | — |

> **[변경] Controller ↔ Sensor Aggregation 실제 인스턴스 수:**  
> v1: ObstacleSensor 3개(FRONT·LEFT·RIGHT) + DustSensor 1개 = 총 4개  
> v2: ObstacleSensor 2개(FRONT·LEFT) + DustSensor 1개 = 총 3개  
> 다중성 표기 `1..*`는 유지 (최솟값 요건 충족).

---

## 4. 열거형 (Enumeration) 정의

| Enum | 값 | 사용 클래스 | 변경 |
|------|----|------------|------|
| **RVCState** | CLEANING, STOPPED, TURNING, REVERSING | RVC | — |
| **Direction** | FORWARD, BACKWARD, LEFT, RIGHT | MovementUnit | — |
| **PowerLevel** | NORMAL, BOOSTED | CleaningUnit | — |
| **SensorStatus** | ACTIVE, ERROR | Sensor | — |
| **SensorPosition** | FRONT, LEFT ~~, RIGHT~~ | ObstacleSensor | **[변경]** |

> **[삭제] `SensorPosition.RIGHT`:**  
> v1에서는 `SensorPosition`이 FRONT · LEFT · RIGHT 세 값을 가졌다.  
> v2에서는 우측 HW 센서가 제거되어 `RIGHT` 값이 삭제되고 FRONT · LEFT 두 값만 존재한다.  
> 우측 방향 확인은 `MovementUnit.turn(Direction::RIGHT)` 후 `front:ObstacleSensor.isObstacleDetected()` 호출로 대체된다.

---

## 5. Domain Model → Design Class Diagram 주요 변경

| 항목 | Domain Model (v2) | Design Class Diagram (v2) |
|------|-------------------|--------------------------|
| 메서드 | 없음 | SSD System Operations 기반 도출 |
| Controller 공개 API | 없음 | `reportObstacle`, `reportDust`, `reportSensorError` |
| Sensor.readData() | 없음 | 추상 메서드로 정의 (다형성 적용) |
| Obstacle / Dust 클래스 | 환경 개념으로 존재 | 제거 — ObstacleSensor·DustSensor의 상태값으로 대체 |
| 가시성 표기 | 없음 | `+` public / `-` private 명시 |
